package mani.threads.sync;

public class SynchronisedBlock {

	public static void main(String[] args) {
		Multiplex multiplex = new Multiplex();
		Counter1 counter1 = new Counter1(multiplex);
		Counter2 counter2 = new Counter2(multiplex);
		Thread countThread1 = new Thread(counter1, "Counter1");
		Thread countThread2 = new Thread(counter2, "Counter2");
		countThread1.start();
		countThread2.start();
		try {
			countThread1.join();
			countThread2.join();
			System.out.println("Vacancy -1 " + multiplex.getVacancy1());
			System.out.println("Vacancy -2 " + multiplex.getVacancy2());
		} catch (InterruptedException ie) {
			ie.printStackTrace();
		}
	}

}

class Counter1 implements Runnable {
	private Multiplex multiplex;

	public Counter1(Multiplex multiplex) {
		this.multiplex = multiplex;
	}

	public void run() {
		for (int i = 0; i < 10; i++) {
			multiplex.bookSeat1(2);
			multiplex.bookSeat2(5);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			multiplex.cancelSeat1(1);
			multiplex.cancelSeat2(3);
		}
	}
}

class Counter2 implements Runnable {
	private Multiplex multiplex;

	public Counter2(Multiplex multiplex) {
		this.multiplex = multiplex;
	}

	public void run() {
		for (int i = 0; i < 10; i++) {
			multiplex.bookSeat1(2);
			multiplex.bookSeat2(5);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			multiplex.cancelSeat1(1);
			multiplex.cancelSeat2(3);
		}
	}
}

class Multiplex {
	private int cinemaSeat1;
	private int cinemaSeat2;
	private Object controlCinema1;
	private Object controlCinema2;

	public Multiplex() {
		cinemaSeat1 = 20;
		cinemaSeat2 = 20;
		controlCinema1 = new Object();
		controlCinema2 = new Object();
	}

	public int getVacancy1() {
		return cinemaSeat1;
	}

	public int getVacancy2() {
		return cinemaSeat2;
	}

	public void bookSeat1(int count) {
		synchronized (controlCinema1) {
			if (count < cinemaSeat1) {
				cinemaSeat1 -= count;
			}
		}
		
	}

	public void bookSeat2(int count) {
		synchronized (controlCinema2) {
			if (count < cinemaSeat2) {
				cinemaSeat2 -= count;
			}
		}
		
	}

	public void cancelSeat1(int count) {
		synchronized (controlCinema1) {
			cinemaSeat1 += count;
		}
		
	}

	public void cancelSeat2(int count) {
		synchronized (controlCinema2) {
			cinemaSeat2 += count;
		}
		
	}

}
